<?php

namespace App\Http\Controllers\System;

use App\Model\Foundation\Employee;
use App\Model\Foundation\Student;
use App\Model\Foundation\Teacher;
use App\Model\System\Token;
use App\Model\Wechat\WechatUser;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
//use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Laravel\Lumen\Routing\Controller as BaseController;

use App\Model\System\User;
use App\Events\Event;
use App\Events\StudentEvent;
use App\Http\Controllers\MessagePacket;
use Validator;

class UserController extends BaseController
{
    use MessagePacket;


    /**
     * 获取当前用户
     * @param Request $request
     * @return packetMessage
     */
    function getCurrentUser(Request $request)
    {
        $user = Token::user();
        $user->types = $this->scanner($user);;
        if(empty($user)){
            return $this->fail($user, '数据不存在');
        }else{
            return $this->success($user);
        }
    }

    /**
     * 获取单一用户的信息
     * @param $id
     * @return packetMessage
     */
    function getUser($id)
    {
        $id = intval($id);
        $user = User::find($id);

        if(empty($user)){
            return $this->fail($user, '数据不存在');
        }else{
            return $this->success($user);
        }
    }

    /**
     * 批量查询用户列表
     * @param Request $request
     * @return packetMessage
     */
    function getUsers(Request $request)
    {
        $user = User::whereNotNull('userid');
        $user->where(function ($user) use ($request){
            if($request->has('account')){
                $user->orwhere('account', 'like', "%$request->account%");
            }
            if($request->has('email')){
                $user->orwhere('email', 'like', "%$request->email%");
            }
            if($request->has('number')){
                $user->orwhere('number', 'like', "%$request->number%");
            }
            if($request->has('type')){
                $user->orwhere('type', $request->get('type'));
            }
        });

        # 需要／不需要 分页
        if($request->has('page')) {
            $limit = 30;
            if ($request->has('perPage')) {
                $limit = $request->get('perPage');
            }
            $users = $user->paginate($limit)->toarray();
            $data['list'] = $users['data'];
            unset($users['data']);
            $data['pager'] = $users;
        }else{
            $data = $user->get();
        }

        if(empty($data)){
            return $this->fail($data, '数据不存在');
        }
        return $this->success($data);
    }


    /**
     * 添加一个用户
     * @param Request $request
     * @return packetMessage
     */
    function  addUser(Request $request)
    {
        try{
            $obj = new User($request->all());
            if($request->has('password')){
                $obj->setSecurityCode($request->get('password'));
            }
            $obj->userid = User::generateID();
            $obj->updateCreator();
            $obj->save();
//            if($request->get('type')==User::ADMIN){
//                $this->addEmployee($obj);
//            }elseif ($request->get('type')==User::TEACHER){
//                $this->addTeacher($obj);
//            }else{
//                $this->addStudent($obj);
//            }

            return $this->success($obj);
        }catch (\Exception $e){
            return $this->fail(false,'失败: '.$e->getMessage());
        }

    }


    /**
     * 管理员 更新某个用户的账号信息
     * @param Request $request
     * @return packetMessage
     */
    function  updateUser($id, Request $request)
    {
        try{
            $user = User::find($id);
            if($user->account == 'admin'){
                if(Token::user()->account != 'admin'){
                    return $this->fail(false,'无权限修改此账号名称');
                }
                if($request->get('account') != 'admin'){
                    return $this->fail(false,'无法修改此账号名');
                }

            }
            if($request->has('account')){
                $check = User::where('userid','!=',$id)
                    ->where('account',$request->get('account'))
                    ->first();
                if(!empty($check)){
                    return $this->fail(false,'账号已存在');
                }
            }

            if($request->has('email')){
                $check = User::where('userid','!=',$id)
                    ->where('email',$request->get('email'))
                    ->first();
                if(!empty($check)){
                    return $this->fail(false,'邮箱已存在');
                }
            }
            if($request->has('number')){
                $check = User::where('userid','!=',$id)
                    ->where('number',$request->get('number'))
                    ->first();
                if(!empty($check)){
                    return $this->fail(false,'手机号已存在');
                }
            }
            if(empty($request->get('account')) && empty($request->get('email')) && empty($request->get('number'))){
                return $this->fail('账号，手机号，邮箱必填一项');
            }

            $user->update($request->all());
            if($request->has('password')){
                $user->setSecurityCode($request->get('password'));
            }
            $user->updateModifier();

            if($user->save()){
                return $this->success($user,'修改成功');
            }else{
                return $this->fail(false,'保存失败');
            }
        }catch (\Exception $e){
            return $this->fail(false,'修改失败',$e->getMessage());
        }

    }




    /**********************************************************************
     *              以上是不对外开发的接口，只供用后台管理使用
     **********************************************************************/



    /**
     * 检查用户账号是否存在
     * @param Request $request
     * @return array
     */
    function checkUser(Request $request)
    {
        $fails = [];
        if($request->has('account')){
            $email = $request->get('account');
            $user = User::where('account', $email)->first();
            if($user) $fails[] = 'account';
        }
        if($request->has('email')){
            $email = $request->get('email');
            $user = User::where('email', $email)->first();
            if($user) $fails[] = 'email';
        }
        if($request->has('number')){
            $number = $request->get('number');
            $user = User::where('number', $number)->first();
            if($user) $fails[] = 'number';
        }

        if(empty($user)){
            return $this->success(false);
        }else{
            return $this->success($fails);
        }
    }

    /**
     * 注册一个用户
     * @param Request $request
     * @return packetMessage
     */
    function  register(Request $request)
    {
        try{
            $fails = [];

            if($request->has('account')){
                $acc = $request->get('account');
                if(!empty($acc)){
                    $user = User::where('account', $acc)->first();
                    if($user) $fails[] = 'account';
                }
            }
            if($request->has('email')){
                $email = $request->get('email');
                if(!empty($email)) {
                    $user = User::where('email', $email)->first();
                    if ($user) $fails[] = 'email';
                }
            }
            if($request->has('number')){
                $number = $request->get('number');
                if(!empty($number)) {
                    $user = User::where('number', $number)->first();
                    if ($user) $fails[] = 'number';
                }
            }
            if(!empty($fails)){
                return $this->success($fails);
            }

            $id = User::generateID();
            $obj = new User($request->all());
            $obj->type = User::STUDENT;
            $obj->userid = $id;
            if($request->has('password')){
                $obj->setSecurityCode($request->get('password'));
            }else{
                throw  new \Exception('缺少密码字段');
            }
            $obj->save();
            $obj->userid = $id;
            $this->addStudent($obj, $request);

            return $this->success(true);
        }catch (\Exception $e){
            return $this->fail(false, '错误: '.$e->getMessage());
        }
    }


    /**
     * 用户修改密码
     * @param Request $request
     * @param $id
     * @return array
     */
    function changepwd(Request $request, $id)
    {
        if($request->has('password')){
            $password = $request->get('password');
        }else{
            return $this->fail(false);
        }
        if($request->has('oldpassword')){
            $oldpassword = $request->get('oldpassword');
        }else{
            return $this->fail(false);
        }
        $obj = User::find($id);
        if($obj->password == User::getSecurityCode($oldpassword)){
            $obj->setSecurityCode($password);
            $obj->save();
            return $this->success(true);
        }
        return $this->fail(false);
    }



    /**
     * 用户登录
     * @param Request $request
     * @return packetMessage
     */
    function login(Request $request, Response $response)
    {
        $account = $request->get('account');
        $user = User::where('islock', 0)
            ->where('password', User::getSecurityCode($request->get('password')))
            ->where(
                function($query)use($account){
                    $query->where('email', $account)->orwhere('number', $account)->orwhere('account', $account);
                })
            ->first();
        if($user){
            $token = $user->setToken($user->userid);
            app('session')->put('token',$token);
            $user->types = $this->scanner($user);
            return $this->success($user);
        }else{
            return $this->fail($user,'登录失败');
        }
    }


    /**
     * 绑定Openid
     * @param Request $request
     * @return packetMessage
     */
    protected function bindOpenid($openid,$user)
    {

        $count = WechatUser::where('openid',$openid)->first();
        if(!$count){
            $wechat = new WechatUser();
            $wechat->userid = $user->userid;
            $wechat->openid = $openid;
            $wechat->save();
        }
    }

    /**
     * 绑定Openid
     * @param Request $request
     * @return packetMessage
     */
    public function bindType(Request $request)
    {
        if($request->has('type') && app('session')->get('openid') && app('session')->get('url'))
        {
            $wechat = WechatUser::where('openid',app('session')->get('openid'))->first();
            if($wechat){
                $wechat->identity = $request->get('type');
                $wechat->save();
                return $this->success(app('session')->get('url'));
            }
        }else{
            return $this->fail(false,'缺少参数');
        }

    }



    /**
     * Openid登录
     * @param Request $request
     * @return packetMessage
     */
    public function openidLogin(Request $request)
    {
        $session = app('session');
        if($session->get('openid') && $session->get('url'))
        {
            $wechat = WechatUser::where('openid',$session->get('openid'))->first();
            if($wechat){
                ## openid免密登录
                $userid = $wechat->userid;
                $user = User::where('islock', 0)
                    ->where('userid',$userid)
                    ->first();
                if($user){
                    $token = $user->setToken($user->userid);
                    app('session')->put('token',$token);
                    $user->types = $this->scanner($user);
                    $temp = [];
                    foreach ($user->types as $type){
                        if($type != 1){
                            $temp[] = $type;
                        }
                    }
                    $user->types = $temp;
                    if($wechat->identity){
                        $user->wechat_type = $wechat->identity;
                    }
                    $user->url = $session->get('url');
                    return $this->success($user);
                }else{
                    return $this->fail($user,'登录失败');
                }
            }else{
                ## 账号登录+绑定openid
                $account = $request->get('account');
                $user = User::where('islock', 0)
                    ->where('password', User::getSecurityCode($request->get('password')))
                    ->where(
                        function($query)use($account){
                            $query->where('email', $account)->orwhere('number', $account)->orwhere('account', $account);
                        })
                    ->first();
                if($user){
                    $this->bindOpenid($session->get('openid'),$user);
                    $token = $user->setToken($user->userid);
                    app('session')->put('token',$token);
                    $user->types = $this->scanner($user);
                    $temp = [];
                    foreach ($user->types as $type){
                        if($type != 1){
                            $temp[] = $type;
                        }
                    }
                    $user->types = $temp;
                    $user->url = $session->get('url');
                    return $this->success($user);
                }else{
                    return $this->fail($user,'登录失败');
                }
            }
        }else{
            return $this->fail(false,'缺少参数');
        }
    }


    /**
     * 用户登出
     * @param Request $request
     * @return packetMessage
     */
    function logout()
    {
        try{
            $token = app('session')->get('token');
            $user = Token::user();
            if($user){
                $token = Token::where('token',$token)->first();
                $token->delete();
                app('session')->put('token','');
                unset($user->types);
                $user->save();

            }
            return $this->success(true);
        }catch (\Exception $e){
            return $this->fail($user,'登出失败');
        }
    }

    /**
     * 发送重置密码邮件
     * @param Request $request
     * @return packetMessage
     */
    function verifyMail(Request $request)
    {
        if(!$request->has('email')){
            return $this->fail(false,'邮箱参数不全');
        }
        $email = $request->input('email');
        $rules = ['email' => 'required|email'];
        $messages = [
            'required' => '邮箱不能为空',
            'email' => '邮箱格式不对'
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            return $this->fail(false,'邮箱格式不对');
        }
        $user = User::where('email', $email)->first();
        if (empty($user)) {
            return $this->fail($user, '此用户不存在');
        }

        $time = time();
        $userid = $user->userid;
        $token = md5($userid . $time . User::USERSALT);
        $toMail  = $email;

        $url = 'http://'.$request->server('HTTP_HOST').'/api/user/password/link?userid='.$userid.'&tmp='.$time.'&token='.$token;
        $url = "<a href='$url'> $url</a>";
        return $this->sendMail($toMail,$url);
    }

    function sendMail($toMail,$url){
        $mail = new \PHPMailer();
        $mail->IsSMTP();

        $mail->Host = env('MAIL_HOST');
        $mail->SMTPAuth = true;
        $mail->CharSet = 'UTF-8';
        $mail->Username = env('MAIL_USERNAME');
        $mail->Password = env('MAIL_PASSWORD');
        $mail->From = env('MAIL_FROM_ADDRESS');
        $mail->FromName = env('MAIL_FROM_NAME');
        $mail->AddAddress($toMail);
        $mail->WordWrap = 50;
        $mail->IsHTML(true);

        $mail->Subject = "请重置eeo的密码";
        $mail->Body = "请点击下面的链接重置密码".$url;
        $mail->AltBody = "请使用HTML方式查看邮件";

        $email = explode('@',$toMail);
        if($email[1] == 'gmail.com'){
            $email = 'mail.google.com';
        }else{
            $email = 'mail.'.$email[1];
        }
        if ($mail->Send()){
            return $this->success($email);
        }
        else{
            return $this->fail($mail, '邮件发送失败');
        }
    }

    /**
     * 重置密码：验证链接中url有效性
     * @param Request $request
     * @return packetMessage
     */
    function verifyUrl(Request $request)
    {
        $fields = $request->all();
        $key = User::USERSALT;
        $timestamp = $fields['tmp'];
        $expired = 3600;
        if(env('expired')){
            $expired = env('expired');
        }
        if($fields['token'] == md5($fields['userid'].$timestamp.$key)){
            if(time() - $timestamp > $expired){
                return $this->fail(false, '该链接已过期');
            }
            else{
                return redirect('home/forget_ok.html?id='.$fields['userid']);
            }
        }
        else{
            return $this->fail(false, '无效的参数');
        }
    }

    /**
     * 重置密码
     * @param Request $request
     * @return packetMessage
     */
    function resetPassword(Request $request)
    {
        if(!$request->has('password') || !$request->has('password_confirmation')){
            return $this->fail(false, '参数不全');
        }
        $data = $request->all();
        $password = $request->input('password');

        $rules = [
            'password'=>'required|between:6,20|confirmed',
        ];
        $messages = [
            'required' => '密码不能为空',
            'between' => '密码必须是6~20位之间',
            'confirmed' => '新密码和确认密码不匹配'
        ];
        $validator = Validator::make($data, $rules, $messages);

        if ($validator->fails()) {
            return $this->fail(false,'无效的密码');
        }

        $user = User::find($data['userid']);

        $user->setSecurityCode($password);

        if($user->save()){
            return $this->success($user);
        }
        return $this->fail(false,'密码设置失败');
    }

    /**
     * 创建token
     * @param $result
     * @return Response
     */
    protected function token($result)
    {
        $response = new \Illuminate\Http\Response($this->success($result));
        return $response;
    }

    /**
     * 添加学生
     * @param User $user
     * @param Request $request
     * @throws \Exception
     */
    protected function addStudent(User $user, Request $request)
    {
        try{
            $student = new Student();
            $student->userid = $user->userid;
            $student->email = $user->email;
            $student->mobile = $user->number;
            $student->name = $request->get('nickname');
            $student->ClassInNo = $user->number;
            $event = new StudentEvent($student, Event::CREATE, $request->get('password'));
            event($event);
            $student->save();
        }catch (\Exception $e){
            throw  $e;
        }
    }

    /**
     * @param User $user
     */
    protected function addTeacher(User $user)
    {
        $stuf = new Teacher();
        $stuf->userid = $user->userid;
        $stuf->email =  $user->email;
        $stuf->mobile = $user->number;
        $stuf->save();
    }

    /**
     * @param User $user
     */
    protected function addEmployee(User $user)
    {
        $stuff = new Employee();
        $stuff->userid = $user->userid;
        $stuff->email = $user->email;
        $stuff->number = $user->number;
        $stuff->save();
    }

    /**
     * @param User $user
     * @return array
     */
    protected function scanner(User $user)
    {
        return User::getUserTypes($user->userid);
    }


}
